/*******************************************************************************
 * Copyright (c) 2011 Irineu Martins de Lima Moura (imlm2).
 * This file is part of JBeat.
 * 
 *     JBeat is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     JBeat is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with JBeat.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Irineu Martins de Lima Moura (imlm2) - initial API and implementation
 ******************************************************************************/
package br.ufpe.cin.imlm2.jbeat.soot.common;

import java.util.Collection;

import soot.SootClass;
import soot.SootMethod;
import soot.tagkit.Host;

/**
 * An abstract Tagger of concrete methods.
 * 
 * @author Irineu
 */
public abstract class MethodTagger extends Tagger {

	public MethodTagger( CommonOptions options ) {
		super( options );
	}

	public MethodTagger() {
		super( new CommonOptions() );
	}

	@Override
	protected void executePostTaggingTransformations() {
		// Empty.
	}

	@Override
	protected void executePreTaggingTransformations() {
		// Empty.
	}

	@Override
	protected void resolveTargetSet() {
		CommonOptions opts = (CommonOptions) this.getOptions();
		Collection<SootClass> classes;
		if ( opts.isAnalyzeLibraries() )
			classes = SceneWrapper.getAllClassesAndInterfaces();
		else
			classes = SceneWrapper.getAllApplicationClassesAndInterfaces();

		for ( SootClass sootClass : classes ) {
			for ( SootMethod sootMethod : sootClass.getMethods() ) {
				if ( sootMethod.isConcrete() ) {
					this.getTargetSet().add( sootMethod );
				}
			}
		}

	}

	@Override
	protected void tag() {
		for ( Host h : this.getTargetSet() ) {
			this.checkTags( (SootMethod) h );
		}

	}

	/**
	 * Verifies if method <code>m</code> has the tag(s) used by this tagger, if
	 * not a new one is created and added.
	 * 
	 * @param m
	 */
	protected abstract void checkTags( SootMethod m );

}
